﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using PasteLoggerBoard.redismodel;
using PasteLoggerBoard.usermodels;
using Volo.Abp.DependencyInjection;
using Volo.Abp.ObjectMapping;

namespace PasteLoggerBoard
{
    /// <summary>
    /// 
    /// </summary>
    public class ModelHelper : ISingletonDependency
    {
        private IAppCache _cache;
        private IServiceProvider _serviceProvider;
        private readonly IObjectMapper ObjectMapper;



        //scop
        //protected readonly HttpContext _httpContext;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceProvider"></param>
        /// <param name="cache"></param>
        /// <param name="map"></param>
        public ModelHelper(IServiceProvider serviceProvider, IAppCache cache, IObjectMapper map)
        {
            this._serviceProvider = serviceProvider;
            _cache = cache;
            ObjectMapper = map;
        }



        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="id"></param>
        ///// <returns></returns>
        //public async Task<PartInfoDto> ItemPartInfo(int id)
        //{
        //    var item = await _cache.GetAsync<PartInfoDto>($"{PublicString._cacheheadpart}{id}");
        //    if (item == null || item == default)
        //    {
        //        using var _scope = _serviceProvider.CreateScope();
        //        using var _dbContext = _scope.ServiceProvider.GetRequiredService<PasteLoggerBoardDbContext>();
        //        var find = _dbContext.PartInfo.Where(x => x.Id == id).AsNoTracking().FirstOrDefault();
        //        if (find != null && find != default)
        //        {
        //            item = ObjectMapper.Map<PartInfo, PartInfoDto>(find);
        //            await _cache.SetAsync<PartInfoDto>($"{PublicString._cacheheadpart}{id}", item, 3600);
        //        }
        //    }
        //    return item;
        //}

        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="id"></param>
        ///// <returns></returns>
        //public async Task<bool> RemovePartItemCacheAsync(int id)
        //{
        //    return await _cache.DeleteAsync($"{PublicString._cacheheadpart}{id}");
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<UserInfoDto> ItemUserInfo(int id)
        {
            var item = await _cache.GetAsync<UserInfoDto>($"{PublicString._cacheheaduser}{id}");
            if (item == null || item == default)
            {
                using var _scope = _serviceProvider.CreateScope();
                using var _dbContext = _scope.ServiceProvider.GetRequiredService<PasteLoggerBoardDbContext>();
                var find = _dbContext.UserInfo.Where(x => x.Id == id).AsNoTracking().FirstOrDefault();
                if (find != null && find != default)
                {
                    item = ObjectMapper.Map<UserInfo, UserInfoDto>(find);
                    await _cache.SetAsync<UserInfoDto>($"{PublicString._cacheheaduser}{id}", item, 3600);
                }
            }
            return item;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<bool> RemoveUserItemCacheAsync(int id)
        {
            return await _cache.DeleteAsync($"{PublicString._cacheheaduser}{id}");
        }


        ///// <summary>
        ///// 获取自己级下级账号列表 缓存30~70秒
        ///// </summary>
        ///// <param name="_dbContext"></param>
        ///// <param name="userid"></param>
        ///// <returns></returns>
        ///// <exception cref="PasteLoggerBoardException"></exception>
        //public async Task<List<UserInfoListDto>> ReadMyAndNextUserList(IPasteLoggerBoardDbContext _dbContext, int userid)
        //{

        //    //可以做缓存处理
        //    var find = await _cache.GetAsync<List<UserInfoListDto>>(string.Format(PublicString.CacheMyNextUserList, userid));
        //    if (find != null && find.Count > 0)
        //    {
        //        return find;
        //    }
        //    //获取我的部门
        //    var mypart = await (from a in _dbContext.BindUserPart.Where(x => x.UserId == userid)
        //                        join b in _dbContext.PartInfo on a.PartId equals b.Id into c
        //                        from d in c.DefaultIfEmpty()
        //                        select new PartInfoListDto()
        //                        {
        //                            Id = d.Id,
        //                            Name = d.Name,
        //                            FatherStr = d.FatherStr
        //                        }).AsNoTracking().ToListAsync();

        //    if (mypart != null && mypart.Any())
        //    {
        //        IQueryable<int> query = null;
        //        foreach (var item in mypart)
        //        {
        //            var one = _dbContext.PartInfo.Where(x => x.Id != item.Id && x.FatherStr.StartsWith(item.FatherStr)).Select(x => x.Id);
        //            if (query == null)
        //            {
        //                query = one;
        //            }
        //            else
        //            {
        //                query = query.Union(one);
        //            }
        //        }
        //        if (query != null)
        //        {
        //            var userdtolist = await (from a in _dbContext.BindUserPart.Where(x => query.Contains(x.PartId))
        //                                     join b in _dbContext.UserInfo on a.UserId equals b.Id into d
        //                                     from f in d.DefaultIfEmpty()
        //                                     select new UserInfoListDto()
        //                                     {
        //                                         Id = f.Id,
        //                                         UserName = f.UserName,
        //                                         UserHead = f.UserHead
        //                                     }).Distinct().ToListAsync();

        //            //把自己加上去
        //            if (!userdtolist.Select(x => x.Id).Contains(userid))
        //            {
        //                var myuser = _dbContext.UserInfo.Where(x => x.Id == userid).AsNoTracking().FirstOrDefault();
        //                if (myuser != null && myuser != default)
        //                {
        //                    userdtolist.Insert(0, ObjectMapper.Map<UserInfo, UserInfoListDto>(myuser));
        //                }
        //            }

        //            _cache.Set<List<UserInfoListDto>>(string.Format(PublicString.CacheMyNextUserList, userid), userdtolist, new Random().Next(30, 70));

        //            return userdtolist;
        //        }
        //        else
        //        {
        //            throw new PasteLoggerBoardException("没有获取到下级部门的绑定信息，无法获取");
        //        }
        //    }
        //    else
        //    {
        //        throw new PasteLoggerBoardException("当前账号没有绑定部门信息，无法获取");
        //    }

        //}


        ///// <summary>
        ///// 判定一个账号是否有另外一个账号的所属权，一般用于上下级的判定
        ///// </summary>
        ///// <param name="_dbContext"></param>
        ///// <param name="userid"></param>
        ///// <param name="targetuserid"></param>
        ///// <returns></returns>
        //public async Task<bool> HasUserRole(IPasteLoggerBoardDbContext _dbContext, int userid, int targetuserid)
        //{
        //    var userdtolist = await ReadMyAndNextUserList(_dbContext, userid);
        //    if (userdtolist.Any())
        //    {
        //        if (userdtolist.Select(x => x.Id).Contains(targetuserid))
        //        {
        //            return true;
        //        }
        //    }
        //    return false;
        //}


        /// <summary>
        /// 是否有权限
        /// </summary>
        /// <param name="_model"></param>
        /// <param name="_role"></param>
        /// <param name="_token"></param>
        /// <returns></returns>
        public (int code, bool role) HasRole(string _model, string _role, string _token = null)
        {
            if (!string.IsNullOrEmpty(_token))
            {
                var roles = _cache.Get<List<RoleInfoListDto>>(_token);
                if (roles != null && roles.Any())
                {
                    var root = roles.Where(x => (x.Model == "root" && x.Role == "root") || (x.Model == _model && x.Role == _role)).Any();
                    return (403, root);
                }
                else
                {
                    return (401, false);
                }
            }
            return (401, false);
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="_dbContext"></param>
        /// <param name="userid"></param>
        /// <param name="_model"></param>
        /// <param name="_role"></param>
        /// <returns></returns>
        public async Task<bool> HasRole(IPasteLoggerBoardDbContext _dbContext, int userid, string _model, string _role)
        {

            var user = await ItemUserInfo(userid);
            var roles = _dbContext.RoleInfo.Where(x => _dbContext.GradeRole.Where(x => x.GradeId == user.GradeId).Select(x => x.RoleId).Contains(x.Id)).AsNoTracking().ToList();
            if (roles != null && roles.Count > 0)
            {
                return roles.Where(x => (x.Model == "root" && x.Role == "root") || (x.Model == _model && x.Role == _role)).Any();
            }
            return false;
        }



    }
}
